package com.yami.shop.api.controller;

import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.ObjectUtil;
import com.yami.shop.bean.app.param.PayRedEnvelopParam;
import com.yami.shop.bean.app.param.PayUserParam;
import com.yami.shop.bean.dto.red.RedPacketInfoDto;
import com.yami.shop.bean.enums.PayEntry;
import com.yami.shop.bean.model.RedPacketInfo;
import com.yami.shop.bean.model.User;
import com.yami.shop.bean.pay.PayInfoDto;
import com.yami.shop.bean.vo.RedPacketVo;
import com.yami.shop.common.enums.PayType;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.i18n.I18nMessage;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.manager.impl.PayManager;
import com.yami.shop.security.api.model.YamiUser;
import com.yami.shop.security.api.util.SecurityUtils;
import com.yami.shop.security.common.manager.PasswordManager;
import com.yami.shop.service.PayInfoService;
import com.yami.shop.service.RedPacketInfoService;
import com.yami.shop.service.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;

/**
 * @author LHD on 2020/03/02.
 */
@Tag(name = "现金红包支付接口")
@RestController
@RequestMapping("/p/redEnvelope")
@AllArgsConstructor
public class PayRedEnvelopController {
    private final PayManager payManager;
    private final PayInfoService payInfoService;
    private final Snowflake snowflake;
    private final RedPacketInfoService redPacketInfoService;
    private final UserService userService;
    private final PasswordEncoder passwordEncoder;
    private final PasswordManager passwordManager;

    /**
     * 会员支付接口
     */
    @PostMapping("/payRedEnvelope")
    @Operation(summary = "现金红包支付", description = "现金红包支付")
    @SneakyThrows
    @Transactional
    public ServerResponseEntity<?> payRedEnvelope(HttpServletResponse httpResponse, @RequestBody PayRedEnvelopParam payRedEnvelopParam) {
        // 发红包先扣减系统余额，暂时不扣除新生账户余额，领红包任务处理后，扣减新生用户余额
        YamiUser user = SecurityUtils.getUser();
        if (!user.getEnabled()) {
            // 您已被禁用，不能购买，请联系平台客服
            return ServerResponseEntity.showFailMsg(I18nMessage.getMessage("yami.order.pay.user.disable"));
        }
        if (!payRedEnvelopParam.getPayType().equals(PayType.BALANCE.value())) {
            // 请使用余额进行支付
            return ServerResponseEntity.showFailMsg(I18nMessage.getMessage("yami.user.payType.error"));
        }
        if (payRedEnvelopParam.getTotalAmount() == 0 || payRedEnvelopParam.getTotalPacket() == 0) {
            throw new YamiShopBindException("yami.sys.illegalArgument");
        }
        // 最小值判断
        if (payRedEnvelopParam.getTotalPacket() * 0.01 > payRedEnvelopParam.getTotalAmount()) {
            return ServerResponseEntity.showFailMsg(I18nMessage.getMessage("yami.dtc.redpacket.one.min.amount"));
        }
        // 最大值判断
        if (payRedEnvelopParam.getTotalPacket() * 800 < payRedEnvelopParam.getTotalAmount()) {
            return ServerResponseEntity.showFailMsg(I18nMessage.getMessage("yami.dtc.redpacket.one.max.amount"));
        }

        String decryptPassword = passwordManager.decryptPassword(payRedEnvelopParam.getPassword());
        User userData = userService.getById(user.getUserId());
        if (!passwordEncoder.matches(decryptPassword, userData.getPayPassword())) {
            return ServerResponseEntity.showFailMsg(I18nMessage.getMessage("yami.dtc.password.check"));
        }
        String payNo = String.valueOf(snowflake.nextId());
        RedPacketInfoDto redPacketInfoDto = new RedPacketInfoDto();
        // 插入一条红包记录
        redPacketInfoDto.setUserId(user.getUserId());
        redPacketInfoDto.setTitle(payRedEnvelopParam.getTitle());
        redPacketInfoDto.setTotalPacket(payRedEnvelopParam.getTotalPacket());
        redPacketInfoDto.setTotalAmount(payRedEnvelopParam.getTotalAmount());
        redPacketInfoDto.setIsPayed(0);
        redPacketInfoDto.setStatus(0);
        redPacketInfoDto.setType("0");
        RedPacketVo redPacketVo = redPacketInfoService.sendRedPacket(redPacketInfoDto);

        PayUserParam payUserParam = new PayUserParam();
        payUserParam.setPayNo(payNo);
        payUserParam.setPayType(payRedEnvelopParam.getPayType());
        payUserParam.setNeedAmount(payRedEnvelopParam.getNeedAmount());
        payUserParam.setOrderIds(redPacketVo.getRedPacketId());

        PayInfoDto payInfo = payInfoService.redEnvelope(user.getUserId(), payUserParam);

        payInfo.setBizUserId(user.getBizUserId());
        payInfo.setPayType(payRedEnvelopParam.getPayType());
        payInfo.setApiNoticeUrl("/notice/pay/" + PayEntry.RED_ENVELOPE.value() + "/" + payRedEnvelopParam.getPayType());
        payInfo.setReturnUrl(ObjectUtil.isNotEmpty(payRedEnvelopParam.getReturnUrl()) ? payRedEnvelopParam.getReturnUrl() : null);
        payInfo.setPayUserType("0");
        payManager.doPay(httpResponse, payInfo);
        payRedEnvelopParam.setRedPacketId(redPacketVo.getRedPacketId());
        return ServerResponseEntity.success(payRedEnvelopParam);
    }

    @GetMapping("/isPay")
    @Operation(summary = "获取发红包支付信息", description = "获取发红包支付信息")
    public ServerResponseEntity<Integer> isPay() {
        YamiUser user = SecurityUtils.getUser();
        RedPacketInfo redPacketInfo = redPacketInfoService.getMaxCrtTimeByUserId(user.getUserId());
        return ServerResponseEntity.success(redPacketInfo.getIsPayed());
    }
}
